package alex.cicy.monitor;

import com.alibaba.druid.filter.FilterChain;
import com.alibaba.druid.filter.stat.MergeStatFilter;
import com.alibaba.druid.proxy.jdbc.PreparedStatementProxy;
import com.alibaba.druid.proxy.jdbc.ResultSetProxy;
import com.alibaba.druid.proxy.jdbc.StatementProxy;
import com.codahale.metrics.Timer;

import java.sql.SQLException;

import static com.codahale.metrics.MetricRegistry.name;

/**
 * sql����ͳ�Ƶ� graphite
 * Created by Alex on 2015/7/10.
 */
public class SqlMetricsFilter extends MergeStatFilter {

    private String subProject;
    private String ip = MetricsHelper.ip();

    public void setSubProject(String subProject) {
        this.subProject = subProject;
    }

    private String sql(String sql) {
        return this.mergeSql(sql, this.getDbType()).replace('.', '#').replaceAll("\\s+", "@");
    }

    public ResultSetProxy preparedStatement_executeQuery(FilterChain chain, PreparedStatementProxy statement) throws SQLException {
        String sql = statement.getSql();
        Timer timer = MetricsHelper.getMetric().timer(name(subProject, ip.replace('.', '_'), "sql", sql(sql)));
        try (Timer.Context ignored = timer.time()) {
            return super.preparedStatement_executeQuery(chain, statement);
        }
    }

    @Override
    public ResultSetProxy statement_executeQuery(FilterChain chain, StatementProxy statement, String sql) throws SQLException {
        Timer timer = MetricsHelper.getMetric().timer(name(subProject, ip.replace('.', '_'), "sql", sql(sql)));
        try (Timer.Context ignored = timer.time()) {
            return super.statement_executeQuery(chain, statement, sql);
        }
    }

    @Override
    public int preparedStatement_executeUpdate(FilterChain chain, PreparedStatementProxy statement) throws SQLException {
        String sql = statement.getSql();
        Timer timer = MetricsHelper.getMetric().timer(name(subProject, ip.replace('.', '_'), "sql", sql(sql)));
        try (Timer.Context ignored = timer.time()) {
            return super.preparedStatement_executeUpdate(chain, statement);
        }
    }

    @Override
    public int statement_executeUpdate(FilterChain chain, StatementProxy statement, String sql, String[] columnNames) throws SQLException {
        Timer timer = MetricsHelper.getMetric().timer(name(subProject, ip.replace('.', '_'), "sql", sql(sql)));
        try (Timer.Context ignored = timer.time()) {
            return super.statement_executeUpdate(chain, statement, sql, columnNames);
        }
    }

    @Override
    public int statement_executeUpdate(FilterChain chain, StatementProxy statement, String sql, int[] columnIndexes) throws SQLException {
        Timer timer = MetricsHelper.getMetric().timer(name(subProject, ip.replace('.', '_'), "sql", sql(sql)));
        try (Timer.Context ignored = timer.time()) {
            return super.statement_executeUpdate(chain, statement, sql, columnIndexes);
        }
    }

    @Override
    public int statement_executeUpdate(FilterChain chain, StatementProxy statement, String sql, int autoGeneratedKeys) throws SQLException {
        Timer timer = MetricsHelper.getMetric().timer(name(subProject, ip.replace('.', '_'), "sql", sql(sql)));
        try (Timer.Context ignored = timer.time()) {
            return super.statement_executeUpdate(chain, statement, sql, autoGeneratedKeys);
        }
    }

    @Override
    public int statement_executeUpdate(FilterChain chain, StatementProxy statement, String sql) throws SQLException {
        Timer timer = MetricsHelper.getMetric().timer(name(subProject, ip.replace('.', '_'), "sql", sql(sql)));
        try (Timer.Context ignored = timer.time()) {
            return super.statement_executeUpdate(chain, statement, sql);
        }
    }
}
